home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / tracker-4.13.lha / tracker / notes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-15  |  3.0 KB  |  144 lines

  1. /* notes.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: notes.c,v 4.7 1995/02/08 13:14:56 espie Exp $
  6.  * $Log: notes.c,v $
  7.  * Revision 4.7  1995/02/08  13:14:56  espie
  8.  * *** empty log message ***
  9.  *
  10.  * Revision 4.7  1995/02/08  13:14:56  espie
  11.  * *** empty log message ***
  12.  *
  13.  * Revision 4.6  1995/02/01  20:41:45  espie
  14.  * Added color.
  15.  *
  16.  * Revision 4.6  1995/02/01  20:41:45  espie
  17.  * Added color.
  18.  *
  19.  * Revision 4.5  1995/02/01  16:39:04  espie
  20.  * Moved includes to defs.h
  21.  *
  22.  * Revision 4.5  1995/02/01  16:39:04  espie
  23.  * Moved includes to defs.h
  24.  *
  25.  * Revision 4.0  1994/01/11  17:50:04  espie
  26.  * Makes use of autoinit. Uses less memory, starts up faster.
  27.  * auto_init'd create_notes_table(),
  28.  * suppressed note_name static table,
  29.  * use name_of_note() instead (about 120 * 8 bytes gain).
  30.  * Amiga support.
  31.  * Added finetune.
  32.  */
  33.  
  34. #include "defs.h"
  35.  
  36. #include <ctype.h>
  37. #include <assert.h>
  38. #include <math.h>
  39.  
  40. #include "song.h"
  41. #include "channel.h"
  42. #include "extern.h"
  43.  
  44. ID("$Id: notes.c,v 4.7 1995/02/08 13:14:56 espie Exp $")
  45.  
  46.  
  47. /* we can put it autoinit since find_note is ALWAYS called
  48.  * prior to finding note values !
  49.  */
  50. LOCAL void create_notes_table P((void));
  51. LOCAL void (*INIT)P((void)) = create_notes_table;
  52.  
  53.  
  54. /* the musical notes correspond to some specific pitch.
  55.  * It's useful to be able to find them back, at least for
  56.  * arpeggii.
  57.  */
  58. short pitch_table[NUMBER_NOTES][NUMBER_FINETUNES];
  59.  
  60. LOCAL char *note_template = "C-C#D-D#E-F-F#G-G#A-A#B-";
  61.  
  62. /* find_note(pitch): find note corresponding to the stated pitch */
  63. int find_note(pitch)
  64. int pitch;
  65.    {
  66.    int a, b, i;
  67.    
  68.    INIT_ONCE;
  69.  
  70.    if (pitch == 0)
  71.       return -1;
  72.    a = 0;
  73.    b = NUMBER_NOTES-1;
  74.    while(b-a > 1)
  75.       {
  76.       i = (a+b)/2;
  77.       if (pitch_table[i][0] == pitch)
  78.          return i;
  79.       if (pitch_table[i][0] > pitch)
  80.          a = i;
  81.       else
  82.          b = i;
  83.       }
  84.    if (pitch_table[a][0] - FUZZ <= pitch)
  85.       return a;
  86.    if (pitch_table[b][0] + FUZZ >= pitch)
  87.       return b;
  88.    return NO_NOTE;
  89.    }
  90.  
  91. LOCAL void create_notes_table()
  92.    {
  93.    double base, pitch;
  94.    int i, j, k;
  95.  
  96.    for (j = -8; j < 8; j++)
  97.       {
  98.       k = j < 0 ? j + 16 : j;
  99.       base = AMIGA_CLOCKFREQ/440.0/4.0 / pow(2.0, j/96.0);
  100.  
  101.       for (i = 0; i < NUMBER_NOTES; i++)
  102.          {
  103.          pitch = base / pow(2.0, i/12.0);
  104.          pitch_table[i][k] = floor(pitch + 0.5);
  105.          }
  106.       }
  107.     }
  108.  
  109. char *name_of_note(i)
  110. int i;
  111.    {
  112.    static char name[4];
  113.  
  114.    if (i == NO_NOTE)
  115.       return "   ";
  116.    else 
  117.       {
  118.       name[0] = note_template[(i+9)%12 * 2];
  119.       name[1] = note_template[(i+9)%12 * 2 +1];
  120.       name[2] = '0' + (i-3)/12;
  121.       name[3] = 0;
  122.       return name;
  123.       }
  124.    }
  125.    
  126. int transpose_song(s, transpose)
  127. struct song *s;
  128. int transpose;
  129.    {
  130.    int oldt;
  131.    int i, j, n;
  132.  
  133.    if (!s)
  134.       return 0;
  135.    oldt = s->info.transpose;
  136.    for (n = 0; n < s->info.maxpat; n++)
  137.       for (i = 0; i < BLOCK_LENGTH; i++)
  138.          for (j = 0; j < NUMBER_TRACKS; j++)
  139.             if (s->info.pblocks[n].e[j][i].note != NO_NOTE)
  140.                s->info.pblocks[n].e[j][i].note += transpose - oldt;
  141.    s->info.transpose = transpose;
  142.    return oldt;
  143.    }
  144.